#include <sys/timerfd.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/epoll.h>

#include "rs485_dir.h"
#include "rs485_serial.h"

//根据具体的设备修改
//const char default_path[] = "/dev/ttyTHS0";
const char default_path[] = "/dev/ttyUSB0";

#define handle_error(msg) \
       do { perror(msg); exit(EXIT_FAILURE); } while (0)

void print_elapsed_time(void);

static void init_init(void)
{
  rs485_dir_init();
  rs485_dir.set_dev("/dev/rs485_dir_drv", sizeof "/dev/rs485_dir_drv" -1);
  rs485_dir.set_gpio(265, 266);
  rs485_dir.open();
  rs485_ser_init();
  rs485_ser.set_dev("/dev/ttyTHS0", sizeof "/dev/ttyTHS0" - 1);
  rs485_ser.open();
  rs485_ser.set_speed(460800);
  rs485_ser.set_parity(8, 1, 'N');
  rs485_dir.set_mode(SET_MODE);
  rs485_dir.set_mode(RECV_MODE);
  //epoll_timer.create_fd();
}


int main(void)
{
  //uint8_t send_buf[8] = "\x50\x03\x00\x34\x00\x21\xC9\x9D";
  uint8_t send_buf[8] = "\x50\x03\x00\x34\x00\x06\x89\x87";
  uint8_t recv_buf[100];

  /*
  for(int i = 0; i < sizeof send_buf; i++)
    printf("send_buf[%d]: 0x%02x\r\n", i, send_buf[i]);
  printf("len: %ld\r\n",sizeof send_buf);
  */
  int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
  if (timerfd == -1)
  {
    handle_error("timerfd_create");
  }

  int timerfd1 = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
  if (timerfd1 == -1)
  {
    handle_error("timerfd_create");
  }

  struct itimerspec new_value = {};
  new_value.it_value.tv_sec  = 0; // 第一次1s到期
  new_value.it_value.tv_nsec = 100000;

  new_value.it_interval.tv_sec  = 0; // 后续周期是5s cycle
  new_value.it_interval.tv_nsec = 100000;

  if (timerfd_settime(timerfd, 0, &new_value, NULL) == -1)
  {
    handle_error("timerfd_settime");
  }

  //struct itimerspec new_value = {};
  new_value.it_value.tv_sec  = 1; // 第一次1s到期
  new_value.it_value.tv_nsec = 0;

  new_value.it_interval.tv_sec  = 1; // 后续周期是5s cycle
  new_value.it_interval.tv_nsec = 0;
  if (timerfd_settime(timerfd1, 0, &new_value, NULL) == -1)
  {
    handle_error("timerfd_settime");
  }
  print_elapsed_time();
  printf("timer started\n");

 init_init();

  int epollfd = epoll_create1(EPOLL_CLOEXEC); // or epoll_create(1)
  if (epollfd == -1)
  {
    handle_error("epoll_create1");
  }

  struct epoll_event ev;
  ev.events = EPOLLIN; // 表示该文件描述符可以读的时候就触发
  ev.data.fd = timerfd;
  epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &ev);

  ev.events = EPOLLIN; // 表示该文件描述符可以读的时候就触发
  ev.data.fd = timerfd1;
  epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd1, &ev);

  const int maxEvents = 5; // 也可以设置为1
  struct epoll_event events[maxEvents]; 

  int state = 0;
  while (1)
  {
    int nfd = epoll_wait(epollfd, events, maxEvents, -1);
    if (nfd > 0)
    {
      for (int i = 0; i < nfd; ++i)
      {
        if (events[i].data.fd == timerfd)
        {
          uint64_t exp = 0;
          /*
             int ret = read(timerfd, &exp, sizeof(uint64_t));
             if (ret != sizeof(uint64_t)) 
             {
             handle_error("read timerfd");
             }
             */
          if(state ==1)
          {
#if 0 
            int bytes;
            ioctl(serial_fd , TIOCOUTQ ,&bytes);
            printf("bytes: %d\r\n", bytes);
            //state = 2;
            if(bytes == 0)
            {
              state = 2;
              tcflush(serial_fd, TCOFLUSH);
            }
#endif
              int bytes;
              ioctl(rs485_ser.fd, TIOCOUTQ, &bytes);
              if(bytes == 0)
              {
                state = 2;
                tcflush(rs485_ser.fd, TCOFLUSH);
              }
          }
          else if(state == 2)
          {
#if 0 
            int bytes;
            ioctl(serial_fd, FIONREAD, &bytes);
            if(bytes == 71)
            {
              state = 3;
              //tcflush(serial_fd, TCIOFLUSH);
            }
#endif
            rs485_dir.set_mode(RECV_MODE);
            state = 3;
          }
          else if(state == 3)
          {
            int res = read(rs485_ser.fd, recv_buf, 1024);
            state = 4;
            printf("res: %d\n", res);
          }
          else if(state == 4)
          {

          }
          //print_elapsed_time();
        }
        else if(events[i].data.fd == timerfd1)
        {
          if(state == 0)
          {
#if 0 
            write(serial_fd, send_buf, sizeof send_buf);
            //usleep(1);
            int bytes;
            ioctl(serial_fd, TIOCOUTQ, &bytes);
            printf("bytes: %d\r\n", bytes);
            state = 1;
#endif
            rs485_dir.set_mode(SEND_MODE);
            rs485_ser.write(send_buf, sizeof send_buf);
            usleep(1);
            state = 1;
          }
        }
      }
    }
  }



  return 0;

}

void print_elapsed_time(void)
{
  static struct timeval start = {};
  static int first_call = 1;

  if (first_call == 1)
  {
    first_call = 0;
    if (gettimeofday(&start, NULL) == -1)
    {
      handle_error("gettimeofday");
    }
  }

  struct timeval current = {};
  if (gettimeofday(&current, NULL) == -1)
  {
    handle_error("gettimeofday");
  }

  static int old_secs = 0, old_usecs = 0;

  int secs  = current.tv_sec - start.tv_sec;
  int usecs = current.tv_usec - start.tv_usec;
  if (usecs < 0)
  {
    --secs;
    usecs += 1000000;
  }

  usecs = (usecs + 500)/1000; // 四舍五入

  if (secs != old_secs || usecs != old_usecs)
  {
    printf("%d.%04d\n", secs, usecs);
    old_secs = secs;
    old_usecs = usecs;
  }
}

